"""
Task Service for TaskMaster v1
AceFlow v3.0 - Implementation Phase

Handles task CRUD operations with data isolation
"""

from typing import List, Optional
from datetime import datetime
from ..models.database import Task, get_db_manager


class TaskService:
    """Task service for CRUD operations with user data isolation"""

    def __init__(self):
        self.db_manager = get_db_manager()

    def create_task(self, user_id: int, title: str, description: Optional[str],
                   due_date: datetime, priority: int) -> dict:
        """
        Create a new task for user

        Args:
            user_id: User ID (for data isolation)
            title: Task title
            description: Task description
            due_date: Task due date
            priority: Task priority (1=High, 2=Medium, 3=Low)

        Returns:
            dict: Creation result
        """
        try:
            with self.db_manager.get_connection() as conn:
                # Find the next available id
                result = conn.execute("SELECT COALESCE(MAX(id), 0) + 1 FROM tasks")
                next_id = result.fetchone()[0]

                # Insert task with explicit id
                conn.execute("""
                    INSERT INTO tasks (id, user_id, title, description, due_date, priority, status)
                    VALUES (?, ?, ?, ?, ?, ?, 'pending')
                """, [next_id, user_id, title, description, due_date, priority])

                task_id = next_id

                return {
                    "success": True,
                    "message": "任务创建成功",
                    "task_id": task_id
                }

        except Exception as e:
            return {
                "success": False,
                "message": f"任务创建失败: {str(e)}",
                "task_id": None
            }

    def get_user_tasks(self, user_id: int, status: Optional[str] = None) -> List[dict]:
        """
        Get all tasks for a user with optional status filter

        Args:
            user_id: User ID
            status: Optional status filter

        Returns:
            List[dict]: List of user tasks
        """
        try:
            with self.db_manager.get_connection() as conn:
                if status:
                    result = conn.execute("""
                        SELECT id, user_id, title, description, due_date, priority, status, created_at, notified
                        FROM tasks
                        WHERE user_id = ? AND status = ?
                        ORDER BY due_date ASC, priority ASC
                    """, [user_id, status])
                else:
                    result = conn.execute("""
                        SELECT id, user_id, title, description, due_date, priority, status, created_at, notified
                        FROM tasks
                        WHERE user_id = ?
                        ORDER BY due_date ASC, priority ASC
                    """, [user_id])

                tasks = []
                for row in result.fetchall():
                    tasks.append({
                        "id": row[0],
                        "user_id": row[1],
                        "title": row[2],
                        "description": row[3],
                        "due_date": str(row[4]) if row[4] else None,
                        "priority": row[5],
                        "status": row[6],
                        "created_at": str(row[7]) if row[7] else None,
                        "notified": bool(row[8])
                    })

                return tasks

        except Exception:
            return []

    def get_task_by_id(self, task_id: int, user_id: int) -> Optional[dict]:
        """
        Get a specific task by ID with user isolation

        Args:
            task_id: Task ID
            user_id: User ID (for data isolation)

        Returns:
            dict: Task data or None if not found
        """
        try:
            with self.db_manager.get_connection() as conn:
                result = conn.execute("""
                    SELECT id, user_id, title, description, due_date, priority, status, created_at, notified
                    FROM tasks
                    WHERE id = ? AND user_id = ?
                """, [task_id, user_id])

                row = result.fetchone()
                if row:
                    return {
                        "id": row[0],
                        "user_id": row[1],
                        "title": row[2],
                        "description": row[3],
                        "due_date": str(row[4]) if row[4] else None,
                        "priority": row[5],
                        "status": row[6],
                        "created_at": str(row[7]) if row[7] else None,
                        "notified": bool(row[8])
                    }
                return None

        except Exception:
            return None

    def update_task(self, task_id: int, user_id: int, title: Optional[str] = None,
                   description: Optional[str] = None, due_date: Optional[datetime] = None,
                   priority: Optional[int] = None, status: Optional[str] = None) -> dict:
        """
        Update task information

        Args:
            task_id: Task ID
            user_id: User ID (for data isolation)
            title: New title
            description: New description
            due_date: New due date
            priority: New priority
            status: New status

        Returns:
            dict: Update result
        """
        try:
            # Check if task exists and belongs to user
            if not self.get_task_by_id(task_id, user_id):
                return {
                    "success": False,
                    "message": "任务不存在或无权限访问"
                }

            # Build update query dynamically
            update_fields = []
            values = []

            if title is not None:
                update_fields.append("title = ?")
                values.append(title)
            if description is not None:
                update_fields.append("description = ?")
                values.append(description)
            if due_date is not None:
                update_fields.append("due_date = ?")
                values.append(due_date)
            if priority is not None:
                update_fields.append("priority = ?")
                values.append(priority)
            if status is not None:
                update_fields.append("status = ?")
                values.append(status)

            if not update_fields:
                return {
                    "success": False,
                    "message": "没有提供需要更新的字段"
                }

            # Add task_id and user_id to values
            values.extend([task_id, user_id])

            query = f"""
                UPDATE tasks
                SET {', '.join(update_fields)}
                WHERE id = ? AND user_id = ?
            """

            with self.db_manager.get_connection() as conn:
                conn.execute(query, values)

                return {
                    "success": True,
                    "message": "任务更新成功"
                }

        except Exception as e:
            return {
                "success": False,
                "message": f"任务更新失败: {str(e)}"
            }

    def delete_task(self, task_id: int, user_id: int) -> dict:
        """
        Delete a task

        Args:
            task_id: Task ID
            user_id: User ID (for data isolation)

        Returns:
            dict: Deletion result
        """
        try:
            # Check if task exists and belongs to user
            if not self.get_task_by_id(task_id, user_id):
                return {
                    "success": False,
                    "message": "任务不存在或无权限访问"
                }

            with self.db_manager.get_connection() as conn:
                conn.execute(
                    "DELETE FROM tasks WHERE id = ? AND user_id = ?",
                    [task_id, user_id]
                )

                return {
                    "success": True,
                    "message": "任务删除成功"
                }

        except Exception as e:
            return {
                "success": False,
                "message": f"任务删除失败: {str(e)}"
            }

    def get_due_tasks(self, minutes_ahead: int = 30) -> List[dict]:
        """
        Get tasks that are due within specified minutes
        Used for notification system

        Args:
            minutes_ahead: Minutes ahead to check for due tasks

        Returns:
            List[dict]: List of due tasks
        """
        try:
            with self.db_manager.get_connection() as conn:
                result = conn.execute("""
                    SELECT id, user_id, title, description, due_date, priority, status, notified
                    FROM tasks
                    WHERE status IN ('pending', 'in_progress')
                    AND notified = FALSE
                    AND due_date <= datetime('now', '+{} minutes')
                    AND due_date > datetime('now')
                """.format(minutes_ahead))

                tasks = []
                for row in result.fetchall():
                    tasks.append({
                        "id": row[0],
                        "user_id": row[1],
                        "title": row[2],
                        "description": row[3],
                        "due_date": row[4],
                        "priority": row[5],
                        "status": row[6],
                        "notified": bool(row[7])
                    })

                return tasks

        except Exception:
            return []

    def mark_task_notified(self, task_id: int, user_id: int) -> bool:
        """
        Mark a task as notified

        Args:
            task_id: Task ID
            user_id: User ID

        Returns:
            bool: Success status
        """
        try:
            with self.db_manager.get_connection() as conn:
                conn.execute("""
                    UPDATE tasks
                    SET notified = TRUE
                    WHERE id = ? AND user_id = ?
                """, [task_id, user_id])
                return True
        except Exception:
            return False


# Global task service instance
task_service = TaskService()


def get_task_service() -> TaskService:
    """Get task service instance"""
    return task_service
